import { _decorator, BoxCollider2D, Collider2D, Component, Contact2DType, director, EPhysics2DDrawFlags, IPhysics2DContact, math, Node, physics, PhysicsSystem, PhysicsSystem2D, v3, Vec3 } from 'cc';
import { ShiBingBase } from '../Base/ShiBingBase';
import { FlyObjectLayer } from '../ModuleLayer/FlyObjectLayer';
import { ModuleMgr } from '../../../FrameWork3.8.6/FrameWork/Module/ModuleMgr';
import { CharacterBase } from '../Base/CharacterBase';
import { Player } from './Player';
const { ccclass, property } = _decorator;

@ccclass('Arrow')
export class Arrow extends Component {

    //当前弓箭的最大高度
    private _maxHeight:number=1000;
    //当前弓箭需要射击的最终位置
    private _endPos:Vec3=v3();

    //当前节点出生时的最开始位置
    private _startPos:Vec3=v3();
    private _dir:number=0;//前进方向，从而通过前进方向判断这是玩家士兵的弓箭还是敌人士兵的弓箭
    get dir(){
        return this._dir;
    }
    private _attack:number=0;//当前弓箭的攻击力

    private _arrowName:string="";//唯一识别我是哪个弓箭，方便在容器当中删除

    get arrowName(){
        return this._arrowName;
    }

    private _moveDuration:number=2;//移动总时长2秒
    private _elapsedTime:number=0;//已经过去时长

    //当前弓箭的拥有者
    private _owner:ShiBingBase=null;

    //当前弓箭是否可以再沿着抛物线走
    private _isPaWuXain:boolean=true;


    //父物体的飞行物层
    private _flyObjectLayer:FlyObjectLayer=null;

    set owner(owner:ShiBingBase){
        this._owner=owner;
    }
    get owner(){
        return this._owner;
    }

    onInit(dir:number,attack:number,name:string,endPos:Vec3,owner:ShiBingBase){
        this._isPaWuXain=true;
        //初始化飞行物层
        this._flyObjectLayer=ModuleMgr.instance.getModule<FlyObjectLayer>("FlyObjectLayer");

        this._dir=dir;

        this._attack=attack;

        this._arrowName=name;

        this._endPos=endPos;

        //直接拿到起点的坐标并且克隆一份
        this._startPos=this.node.worldPosition.clone();

        this._owner=owner;


        //对碰撞体进行事件注册
        let collider=this.getComponent(BoxCollider2D);
        if (collider) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
           
        }
        
    }

    //碰撞事件注册
    onBeginContact(selfCollider: BoxCollider2D, otherCollider: BoxCollider2D, contact: IPhysics2DContact | null){
        //console.log("开始碰撞"+selfCollider+","+otherCollider)    
        switch(otherCollider.group){
            case 2:
                let characterBase=otherCollider.node.getComponent(CharacterBase);
                //如果不同方向说明不是一个阵营的敌人
                if(characterBase.QufenDir*this._dir<0){
                    //角色扣血
                    characterBase.hurt(this._attack);
                    //销毁自己
                    this._flyObjectLayer.deleteArrow(this.node);
                }
                break;
            case 4:
                let shiBingBase=otherCollider.getComponent(ShiBingBase);
                if(shiBingBase.dirX*this._dir<0){
                    shiBingBase.hurt(this._attack);
                    //销毁自己
                    this._flyObjectLayer.deleteArrow(this.node);
                }
                break;
        }
    }

    //弓箭的更新方法
    onUpdate(dt:number){
        if(!this._isPaWuXain){
            return;
        }
        //对边界进行处理
        if(this._elapsedTime>=this._moveDuration){
            this._elapsedTime=0;
            this._isPaWuXain=false;
            //这里说明已经到达终点如果没有碰到位置
            this._flyObjectLayer.deleteArrow(this.node);
            return;
        }
        //计算当前进度
        let t=this._elapsedTime/this._moveDuration;
        let currentPos=this.calculatePos(t);
        //更新节点位置与当前旋转
        this.node.setWorldPosition(currentPos);

        //时间自增
        this._elapsedTime+=dt;
    }



    //计算抛物线当前轨迹的方法
    calculatePos(t:number):Vec3{
        //返回当前的位置
        let pos:Vec3=v3();
        pos.x=(this._endPos.x-this._startPos.x)*t+this._startPos.x;
        let y=-0.02*(pos.x-this._startPos.x)*(pos.x-this._endPos.x)+this._startPos.y;
        pos.y=y;
        //顺便将当前物体进行旋转
        let k=-0.015*(2*pos.x-this._startPos.x-this._endPos.x);
        let curDir=v3(1,k);
        if(this.dir<=0){
            curDir=v3(-1,-k);
        }
        //先用向量转弧度
        let radins=Math.atan2(curDir.y,curDir.x);
        //弧度转角度
        let degrees=math.toDegree(radins);
        this.node.angle=degrees;
        return pos;
    }

    
    
}


